import OpenGL.GL as gl
import numpy as np

class RenderTexture2D:
    def __init__(self, level:int, internal_format:int, width:int, 
                 height:int) -> None:
        self.level = level
        self.internal_format = internal_format
        self.createTexture(width, height)

    def bind(self, index: int) -> None:
        gl.glBindTextureUnit(index, self.tex_id)

    def unbind(self, index: int) -> None:
        gl.glBindTextureUnit(index, 0)

    def createTexture(self, width:int, height:int)->None:
        tex = np.empty(1, gl.GLuint)
        gl.glCreateTextures(gl.GL_TEXTURE_2D, 1, tex)
        self.tex_id = tex[0]
        self.width = width
        self.height = height
        gl.glTextureStorage2D(self.tex_id, self.level, self.internal_format, 
                              width, height)

    def delete(self) -> None:
        if gl.glIsTexture(self.tex_id):
            gl.glDeleteTextures(1, self.tex_id)

    def setFiltering(self, min_filter: int, mag_filter: int) -> None:
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_MIN_FILTER, min_filter)
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_MAG_FILTER, mag_filter)

    def setWrapMode(self, wrap_s: int, wrap_t: int) -> None:
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_WRAP_S, wrap_s)
        gl.glTextureParameteri(self.tex_id, gl.GL_TEXTURE_WRAP_T, wrap_t)

    def resize(self, width:int, height:int) -> None:
        if (self.width != width) or (self.height != height):
            gl.glDeleteTextures(1, self.tex_id)
            self.createTexture(width, height)

    def bingImage(self, index: int, level: int, access: int) -> None:
        gl.glBindImageTexture(index, self.tex_id, level,
                           gl.GL_FALSE, 0, access, self.internal_format)
